fix(windows): repair PATHEXT in spawned shells + ESM ripgrep wrapper#484
Conversation
On some Windows Claude Desktop/DXT launches the server process inherits a broken PATHEXT (observed as '.CPL' only). Since child shells are spawned with { ...process.env }, that value propagated into every shell, stripping '.EXE' and breaking resolution of git/node/python/rg and even full-path .exe invocations under PowerShell.
Repair PATHEXT on win32 just before spawn: if '.EXE' is missing, merge the standard list with whatever was present (non-destructive otherwise). Reproduces on x64 too, not only ARM64.
Refs #481
…module) @vscode/ripgrep 1.18.0+ ships package.json with 'type: module'. The MCPB build copies scripts/ripgrep-wrapper.js over the package's lib/index.js, but it was CommonJS (require/module.exports), so it threw 'require is not defined in ES module scope' on import. That throw was swallowed by getRipgrepPath()'s try/catch and surfaced as a misleading 'ripgrep binary not found', silently breaking search on Windows despite the bundled binaries being present. Rewrite the wrapper as ESM (import + export const rgPath, __dirname via fileURLToPath). Refs #481
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR migrates the ripgrep wrapper from CommonJS to ES modules with improved binary resolution fallback logic, and adds Windows-specific PATHEXT environment variable repair to prevent command resolution failures in spawned shell processes when the inherited PATHEXT is corrupted. ChangesWindows Command Execution Reliability
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Two Windows-specific fixes, both surfaced while investigating #481.
Investigates: #481
1. Repair corrupted
PATHEXTbefore spawning shells (the #481 report)On some Windows Claude Desktop / DXT launches, the Desktop Commander server
process inherits a broken
PATHEXT(observed as.CPLonly). Becauseterminal-manager.tsbuilds each child shell's environment from{ ...process.env }, that broken value propagated into every spawned shell,stripping
.EXEand breaking resolution ofgit/node/python/rg(and even full-path
.exeinvocations under PowerShell).Findings that refine the original report:
Windows DXT v0.2.41 launch path generally.
PATHEXT; the value is inherited from how the DXThost launches the server, then faithfully copied to children. Root cause is
upstream (Claude Desktop's DXT launcher), but DC is the right place to defend
since it controls the env handed to child shells.
Fix: on
win32, repairPATHEXTimmediately beforespawn. If.EXEismissing, merge the standard extension list with whatever was present
(non-destructive when
PATHEXTis already healthy).2. Make the bundled ripgrep wrapper ESM
@vscode/ripgrep1.18.0+ shipspackage.jsonwith"type": "module". TheMCPB build copies
scripts/ripgrep-wrapper.jsover the package'slib/index.js, but the wrapper was CommonJS (require/module.exports), soit threw
require is not defined in ES module scopeon import. That throw wasswallowed by
getRipgrepPath()'stry/catchand surfaced as a misleadingripgrep binary not found, silently breakingstart_searchon Windows eventhough the bundled binaries were present.
Fix: rewrite the wrapper as ESM (
import+export const rgPath,__dirnameviafileURLToPath). Verified with a fresh Node import against thedeployed extension:
rgPathresolves torg-x86_64-pc-windows-msvc.exeand thebinary exists.
Testing
tsc --noEmit: no new type errors from these changes.import()against the bundled package onWindows x64 — named
rgPathexport resolves and the target binary exists..CPLvalue at process level on x64, and thatrestoring
PATHEXTmakesgit/node/etc. resolve again.Notes
DXT launcher, but this PR lets DC self-heal without waiting on that.
Summary by CodeRabbit
Bug Fixes
Improvements